﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Net;

namespace GA.Shared.Objects
{
    [Serializable]
    public class Authentication
    {
        /// <summary>
        /// Gets the encrypted Username.
        /// </summary>
        
        public byte[] Username
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the encrypted Password.
        /// </summary>
        
        public byte[] Password
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the IPAddress associated with the authentication.
        /// </summary>
        
        public IPAddress IPAddress
        {
            get;
            private set;
        }

        /// <summary>
        /// Default constructor. Required for serialization.
        /// </summary>
        public Authentication()
        {
        }

        /// <summary>
        /// Constructor for sending username/password information across the internet.
        /// </summary>
        /// <param name="username">Unencrypted string of the username.</param>
        /// <param name="password">Unencrypted string of the password.</param>
        /// <remarks>This procedure automatically encrypts the username and password.</remarks>
        public Authentication(string username, string password, RijndaelManaged authenticator, IPAddress ipAddress)
        {
            if (username == null) throw new ArgumentNullException("username");
            if (username.Length == 0) throw new ArgumentException("username cannot be null", "username");
            if (password == null) throw new ArgumentNullException("password");
            if (password.Length == 0) throw new ArgumentException("password cannot be null", "password");
            if (authenticator == null) throw new ArgumentNullException("authenticator");

            Username = EncryptString(username, authenticator);
            Password = EncryptString(password, authenticator);
            IPAddress = ipAddress;
        }

        private byte[] EncryptString(string encrypt, RijndaelManaged authenticator)
        {
            MemoryStream memoryStream = new MemoryStream();
            try
            {
                ICryptoTransform encryptor = authenticator.CreateEncryptor();
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
                    {
                        streamWriter.Write(encrypt);
                    }
                }
            }
            finally
            {
                authenticator.Clear();
            }
            return memoryStream.ToArray();
        }
    }
}
